package com.bdmc.web.controller.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bdmc.alarm.domain.AlarmRule;
import com.bdmc.alarm.domain.vo.AlarmRuleVo;
import com.bdmc.alarm.service.IAlarmRuleService;
import com.bdmc.base.domain.BaseDevice;
import com.bdmc.base.domain.BaseFacility;
import com.bdmc.base.service.IBaseCarService;
import com.bdmc.base.service.IBaseDeviceService;
import com.bdmc.base.service.IBaseFacilityService;
import com.bdmc.common.core.domain.AjaxResult;
import com.bdmc.common.utils.DateUtils;
import com.bdmc.common.utils.StringUtils;
import com.bdmc.device.domain.DevFacilityHistory;
import com.bdmc.device.domain.DevFacilityRealtime;
import com.bdmc.device.domain.bo.DevGpsHistoryBo;
import com.bdmc.device.domain.vo.DevGpsHistoryVo;
import com.bdmc.device.service.IDevFacilityHistoryService;
import com.bdmc.device.service.IDevFacilityRealtimeService;
import com.bdmc.device.service.IDevGpsHistoryService;
import com.bdmc.report.domain.ReportPersonMiles;
import com.bdmc.report.service.IReportCarMilesService;
import com.bdmc.report.service.IReportPersonMilesService;
import com.bdmc.task.domain.vo.PersonWorkTimeVo;
import com.bdmc.task.service.ITaskPlanDetailService;
import com.xxl.job.core.context.XxlJobHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@RestController
@RequestMapping("/api/north")
public class NorthController {

    @Autowired
    IBaseDeviceService devSvs;

    @Autowired
    IBaseFacilityService facilityService;

    @Autowired
    IDevFacilityRealtimeService facilityRealtimeService;

    @Autowired
    IDevFacilityHistoryService facilityHistoryService;


    @Autowired
    IDevGpsHistoryService gpsHistoryService;

    @Autowired
    IBaseCarService carService;

    @Autowired
    IReportCarMilesService milesService;

    @Autowired
    IReportPersonMilesService personMilesService;

    @Autowired
    ITaskPlanDetailService detailService;

    @Autowired
    IAlarmRuleService ruleService;

    @PostMapping("/test")
    public AjaxResult test() {
        TimeInterval timer = DateUtil.timer();
        timer.start();
        LocalDate first = LocalDate.of(2023, 01, 01);
        LocalDate end = LocalDate.of(2023, 03, 01);
        LocalDate yesterday = first;
        while (yesterday.isBefore(end)) {
            List<PersonWorkTimeVo> workTimeList = detailService.selectPersonDailyWorkTime(LocalDateTimeUtil.formatNormal(yesterday));
            AlarmRuleVo stopRule = ruleService.getVoOne(new LambdaQueryWrapper<AlarmRule>().eq(AlarmRule::getAlarmType, "person_stay"));
            List<ReportPersonMiles> milesList = new ArrayList<>();
            for (PersonWorkTimeVo personWorkTime : workTimeList) {
                if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isEmpty(personWorkTime.getWorkTime()))
                    continue;
                String[] timeSpanArr = personWorkTime.getWorkTime().split(",");
                BigDecimal mileage = new BigDecimal(0);
                long workMin = 0L;
                for (String span : timeSpanArr) {
                    DevGpsHistoryBo bo = new DevGpsHistoryBo();
                    bo.setDevicePhoneNum(personWorkTime.getDevicePhoneNum());
                    bo.setBeginTime(span.split("\\|")[0]);
                    bo.setEndTime(span.split("\\|")[1]);
                    try {
                        List<DevGpsHistoryVo> traceList = gpsHistoryService.traceList(bo);
                        if (traceList != null && traceList.size() > 0) {
                            DevGpsHistoryVo firstVo = traceList.get(0);
                            DevGpsHistoryVo lastVo = traceList.get(traceList.size() - 1);
                            mileage = mileage.add(new BigDecimal(lastVo.getCalcMile()));
                            workMin += LocalDateTimeUtil.between(LocalDateTimeUtil.parse(firstVo.getDataTime().substring(0, 19), DatePattern.NORM_DATETIME_FORMATTER), LocalDateTimeUtil.parse(lastVo.getDataTime().substring(0, 19), DatePattern.NORM_DATETIME_FORMATTER)).toMinutes();
                            long stopSum = traceList.stream().filter(r -> r.getStopMinute() > stopRule.getStopMaxMinute()).mapToLong(DevGpsHistoryVo::getStopMinute).sum();
                            workMin -= stopSum;
                        }
                    } catch (Exception ex) {
                        XxlJobHelper.log(ex);
                    }
                }

                ReportPersonMiles personMiles = new ReportPersonMiles();
                personMiles.setPersonId(personWorkTime.getPersonId());
                personMiles.setFenceId(personWorkTime.getFenceId());
                personMiles.setMiles(mileage);
                personMiles.setDataTime(yesterday);
                personMiles.setCreateBy("xxl-job-admin");
                personMiles.setCreateTime(LocalDateTime.now());
                personMiles.setWorkTime(workMin);
                milesList.add(personMiles);
            }
            XxlJobHelper.log("昨日人员里程计算完成，耗时:" + timer.intervalSecond() + "秒");
            boolean b = personMilesService.saveBatch(milesList);
            yesterday = yesterday.plusDays(1L);
        }
        return AjaxResult.success();
    }



    @PostMapping("/sync")
    public AjaxResult<Void> sync(@RequestBody final String jsonStr) {
        log.info(jsonStr);
        JSONObject json = JSONUtil.parseObj(jsonStr);
        final BaseDevice device = devSvs.getOne(new LambdaQueryWrapper<BaseDevice>().eq(BaseDevice::getImei,json.getStr("imei")));
        if (device != null) {
            long timestamp = json.getLong("eventTime");
            final DevFacilityRealtime dbRealtime = facilityRealtimeService.getOne(new LambdaQueryWrapper<DevFacilityRealtime>().eq(DevFacilityRealtime::getDeviceId,device.getDeviceId()));
            if (dbRealtime == null) {
                return AjaxResult.error("无此设备");
            }
            JSONObject data = json.getJSONObject("data");
            final BigDecimal distance = new BigDecimal(data.getStr("height")).divide(new BigDecimal(10), 2,
                    BigDecimal.ROUND_HALF_UP);
            DevFacilityRealtime newRealtime =  JSONUtil.toBean(data, DevFacilityRealtime.class);
            newRealtime.setDataTime(LocalDateTimeUtil.of(timestamp));
            newRealtime.setDistance(distance);
            newRealtime.setOverflow(data.getInt("full"));
            newRealtime.setRealtimeId(dbRealtime.getRealtimeId());
            newRealtime.setOnlineStatus(1);
            newRealtime.setDeviceId(dbRealtime.getDeviceId());
            facilityRealtimeService.updateById(newRealtime);
            DevFacilityHistory history =  BeanUtil.toBean(newRealtime, DevFacilityHistory.class);
            facilityHistoryService.save(history);

            String alarmMessage = "";
            if (newRealtime.getFire() == 1) {
                alarmMessage = "火灾告警";
            }
            if (newRealtime.getDistance().compareTo(new BigDecimal("70")) < 0) {
                alarmMessage += "\r\n满桶告警";
            }
            if (newRealtime.getBatteryQuantityStatus() == 1) {
                alarmMessage += "\r\n低电量告警";
            }
            if (StringUtils.isNotEmpty(alarmMessage)) {
                BaseFacility resFacility = facilityService.getOne(new LambdaQueryWrapper<BaseFacility>().eq(BaseFacility::getDeviceId,device.getDeviceId()));
                JSONObject jsonObject = new JSONObject();
                jsonObject.putOnce("msgType", 1);// 垃圾桶告警
                jsonObject.set("facilityName", resFacility.getFacilityName());
                jsonObject.set("deviceId", device.getDeviceId());

                jsonObject.set("dataTime",
                        LocalDateTimeUtil.format(newRealtime.getDataTime(),DateUtils.YYYY_MM_DD_HH_MM_SS));
                jsonObject.set("alarmMessage", alarmMessage);
                pushAlarmMessageToClient(jsonObject.toString());
            }
        }
        return AjaxResult.success();
    }

    @GetMapping("facility/list")
    public AjaxResult<List<BaseFacility>> facilityList() {
       return AjaxResult.success(facilityService.list());
    }

    @GetMapping("facility/alarm")
    public AjaxResult<List<DevFacilityRealtime>> facilityAlarm() {
        return AjaxResult.success(facilityRealtimeService.list());
    }

    /**
     * 推送垃圾桶告警信息
     */
    void pushAlarmMessageToClient(String msg) {
//        ExecutorService executor = Executors.newFixedThreadPool(2);
//        executor.submit(() -> {
//            MyWebSocket.sendInfoByDeptId(msg,"1");
//            System.out.println("push task finished!");
//
//        });
    }




}
